Cloudflare Access
Cloudflare Access の認証、初めて使ってみたけどヤバいすな。便利すぎる。Cloudflare でドメイン管理してるならボタンポチポチするだけでパスワードも無い様な画面に簡単に SSO な認証画面作れる。ref Claude Code.icon
Cloudflare Access
概要
Cloudflare Accessは、Zero Trustアクセス制御サービス。アプリケーションの前段に認証・認可レイヤーを置き、VPNなしでセキュアなアクセスを実現する。Cloudflare Zero Trustプラットフォームの中核コンポーネント。
基本概念
従来のVPNモデル:
code:_
ユーザー → VPN → 社内ネットワーク → アプリ(全部見える)
Zero Trust(Access)モデル:
code:_
ユーザー → Cloudflare Access(認証+ポリシー) → 特定のアプリだけ
デフォルト拒否: 全アクセスをまず拒否し、ポリシーに合致する場合のみ許可
リクエスト単位の検証: 一度認証されても毎回ポリシーを評価
アイデンティティベース: IPではなく「誰か」で判断
セットアップの流れ
1. Zero Trustダッシュボードにアクセス
code:_
2. IdP(認証プロバイダ)の設定
Settings → Authentication → Login methods で追加:
table:_
IdP 用途
Google Google Workspace / 個人アカウント
GitHub GitHubアカウント
Okta エンタープライズSSO
Azure AD (Entra ID) Microsoft環境
SAML 汎用SAML 2.0
One-time PIN メールでワンタイムコード送信(IdP不要)
複数のIdPを同時に設定可能。ログイン画面で選択できる。
3. アプリケーションの追加
Access → Applications → Add an application
アプリケーションタイプ
table:_
タイプ 説明
Self-hosted 自前でホストしているWebアプリ
SaaS 外部SaaSアプリ(SAML/OIDC連携)
Private network Cloudflare Tunnelで接続した内部アプリ
Bookmark リンク集(認証なし)
Self-hostedアプリの例
code:_
アプリケーション名: Internal Dashboard
ドメイン: dashboard.example.com
セッション期間: 24時間
4. ポリシーの設定
アプリケーションごとにアクセスポリシーを定義:
code:_
ポリシー名: Allow Engineers
アクション: Allow
条件:
- Emails ending in: @example.com
- GitHub Organization: my-org
- Country: Japan
ポリシーの構成
アクション
table:_
アクション 動作
Allow アクセスを許可
Block アクセスを拒否
Bypass 認証なしでアクセス許可
Service Auth サービス間通信用(トークン認証)
ルール(条件)
table:_
ルールタイプ 意味
Include いずれかに合致すれば対象(OR)
Require すべてに合致する必要あり(AND)
Exclude 合致したら除外
使えるセレクタ
code:_
- Email → 特定のメールアドレス
- Emails ending in → ドメイン単位(@example.com)
- Identity Provider Groups → IdPのグループ
- GitHub Organization → GitHub組織
- Country → 国
- IP Range → IPアドレス範囲
- Access Groups → 再利用可能なグループ
- Certificate (mTLS) → クライアント証明書
- Device Posture → デバイスの状態
- Login Method → 認証方法の指定
Access Groups(再利用可能なグループ)
複数のアプリで共通のポリシーを使い回す:
code:_
グループ名: Engineering Team
Include:
- Emails ending in: @example.com
Require:
- GitHub Organization: my-org
このグループをポリシーの条件として参照できる。
JWTによる認証情報の受け渡し
Accessを通過したリクエストには、JWTが付与される:
code:_
Cookie: CF_Authorization=<JWT>
ヘッダー: Cf-Access-Jwt-Assertion: <JWT>
Workers内でのJWT検証
code:ts
export default {
async fetch(request: Request, env: Env) {
const jwt = request.headers.get("Cf-Access-Jwt-Assertion");
if (!jwt) {
return new Response("Unauthorized", { status: 401 });
}
// JWTのペイロードをデコード(署名検証は後述)
const payload = JSON.parse(atob(jwt.split(".")1)); console.log(payload.email); // ユーザーのメール
console.log(payload.sub); // ユーザーID
console.log(payload.iat); // 発行時刻
console.log(payload.exp); // 有効期限
return new Response(Hello, ${payload.email});
},
};
JWTの署名検証
code:ts
// Accessの公開鍵を取得して検証
const certsUrl = https://<team-domain>.cloudflareaccess.com/cdn-cgi/access/certs;
const certsResponse = await fetch(certsUrl);
const { keys } = await certsResponse.json();
// Web Crypto APIで検証
const key = await crypto.subtle.importKey(
"jwk",
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
false,
);
JWTペイロードの主なフィールド
table:_
フィールド 説明
email ユーザーのメールアドレス
sub ユーザーの一意なID
iss 発行者(team domain)
iat 発行時刻
exp 有効期限
identity_nonce セッション識別子
custom SAML/OIDC属性のカスタムクレーム
Service Tokens(サービス間通信)
人間ではなくサービス(API, CI/CDなど)からのアクセス用:
code:bash
# ダッシュボードで生成するか、APIで作成
# → Client ID と Client Secret が発行される
リクエスト時にヘッダーに付与:
code:bash
curl -H "CF-Access-Client-Id: <client-id>" \
-H "CF-Access-Client-Secret: <client-secret>" \
ポリシーで Service Auth ルールを設定して許可する。
Cloudflare Tunnel との連携
内部ネットワーク上のアプリをインターネットに公開せずにAccessで保護:
code:bash
# Tunnelのインストール
cloudflared tunnel create my-tunnel
# 設定
cloudflared tunnel route dns my-tunnel internal-app.example.com
code:yaml
# config.yml
tunnel: <tunnel-id>
credentials-file: /path/to/credentials.json
ingress:
- hostname: internal-app.example.com
- service: http_status:404
code:_
ユーザー → Cloudflare Access(認証) → Cloudflare Tunnel → 社内のlocalhost:3000
サーバーにインバウンドポートを開ける必要なし
ファイアウォール内のアプリも保護・公開できる
Device Posture(デバイスの状態チェック)
WARP クライアント経由で接続するデバイスの状態をポリシー条件にできる:
table:_
チェック項目 例
OS バージョン macOS 14以上
ディスク暗号化 FileVault有効
ファイアウォール 有効
スクリーンロック 有効
WARP接続状態 接続中
CrowdStrike/SentinelOne エンドポイント保護が稼働中
code:_
ポリシー条件:
Include: Emails ending in @example.com
Require: Device Posture - Disk encryption enabled
ログ・監査
Logs → Access で確認できる:
table:_
情報 説明
ユーザーメール 誰がアクセスしたか
アプリケーション どのアプリにアクセスしたか
アクション Allow / Block
タイムスタンプ いつ
IdP どの認証方法で
国・IP どこから
料金
table:_
プラン 料金 ユーザー数
Free $0 50ユーザーまで
Pay-as-you-go $7/ユーザー/月 無制限
Contract カスタム 無制限
Freeプランでも基本機能は一通り使える。
まとめ:主な構成要素
code:_
┌────────────────────────────────────────────┐
│ ユーザー │
│ (ブラウザ / APIクライアント) │
└──────────────────┬─────────────────────────┘
│
┌──────────▼──────────┐
│ Cloudflare Access │
│ ・IdP認証 │
│ ・ポリシー評価 │
│ ・JWT発行 │
│ ・ログ記録 │
└──────────┬──────────┘
│ (認証済みリクエスト + JWT)
┌──────────▼──────────┐
│ アプリケーション │
│ ・Workers │
│ ・Pages │
│ ・Self-hosted │
│ ・Tunnel経由の内部app │
└─────────────────────┘